package org.dicr.util.jds.gui;

import javax.swing.*;
import javax.swing.event.*;

import org.dicr.event.*;
import org.dicr.gui.*;
import org.dicr.util.jds.*;

import com.borland.dx.dataset.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov, me@dicr.dn.ua
 * @version 030113
 **********************************************************************************************************************/
public class DataNavFilterList extends JList implements DataSetAware, Editable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5330465188930972841L;

	protected boolean ignoreSelectChanges = false;

	protected static final Object allItem = "<Все>";

	protected boolean editable = true;

	protected DataNavFilterListModel model = new DataNavFilterListModel();

	/*******************************************************************************************************************
	 * Конструктор
	 ******************************************************************************************************************/
	public DataNavFilterList() {
		try {
			jbInit();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * Инициализация
	 ******************************************************************************************************************/
	private void jbInit() {
		this.setModel(this.model);
		this.addListSelectionListener(new ListListener());
		this.setAutoscrolls(true);
		this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}

	/*******************************************************************************************************************
	 * Обновляет выделение
	 ******************************************************************************************************************/
	public void updateSelection() {
		try {
			this.ignoreSelectChanges = true;
			Object selectedValue = null;
			if (this.model.getSize() > 0) {
				RowFilterListener listener = this.model.getDataSet().getRowFilterListener();
				if (listener instanceof DataSetFilter) {
					selectedValue = ((DataSetFilter) listener).getFilterValue();
					if (selectedValue == null) selectedValue = allItem;
				}
			}
			if (selectedValue != null) this.setSelectedValue(selectedValue, true);
			else this.clearSelection();
		} finally {
			this.ignoreSelectChanges = false;
		}
	}

	/*******************************************************************************************************************
	 * Обновляет фильтр при смене значения в списке
	 ******************************************************************************************************************/
	protected void updateFilter() {
		try {
			if (this.model.getSize() > 0) {
				Object newValue = this.getSelectedValue();
				if (newValue != null) {
					DataSet dataset = this.model.getDataSet();
					RowFilterListener listener = dataset.getRowFilterListener();
					if (listener instanceof DataSetFilter) {
						DataSetFilter filter = (DataSetFilter) listener;
						Object oldValue = filter.getFilterValue();
						if (oldValue == null) oldValue = allItem;
						if (!oldValue.equals(newValue)) {
							if (newValue.equals(allItem)) newValue = null;
							filter.setFilterValue(newValue);
							dataset.refilter();
						}
					}
				}
			}
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * Устанавливает источник данных
	 ******************************************************************************************************************/
	@Override
    public void setDataSet(DataSet dataset) {
		this.model.setDataSet(dataset);
		updateSelection();
	}

	/*******************************************************************************************************************
	 * Возвращает источник данных
	 ******************************************************************************************************************/
	@Override
    public DataSet getDataSet() {
		return this.model.getDataSet();
	}

	/*******************************************************************************************************************
	 * Установка признака редактируемости
	 ******************************************************************************************************************/
	@Override
    public void setEditable(boolean theEditable) {
		if (this.editable != theEditable) {
			this.editable = theEditable;
			this.setEnabled(theEditable);
		}
	}

	/*******************************************************************************************************************
	 * Возвращает признак редактируемости
	 ******************************************************************************************************************/
	@Override
    public boolean isEditable() {
		return this.editable;
	}

	/*******************************************************************************************************************
	 * Возвращает выбранное значение фильтра
	 ******************************************************************************************************************/
	public Object getFilterValue() {
		return this.getSelectedValue();
	}

	/*******************************************************************************************************************
	 * ######################################################################### Слушатель списка
	 * #########################################################################
	 ******************************************************************************************************************/
	class ListListener implements ListSelectionListener {

		/***************************************************************************************************************
		 * Обработчик событий навигации по списку
		 **************************************************************************************************************/
		@Override
        public void valueChanged(ListSelectionEvent e) {
			if (DataNavFilterList.this.ignoreSelectChanges || e.getValueIsAdjusting() || isSelectionEmpty()) return;
			updateFilter();
		}
	}
}
